package scatter.comment.rest.enjoy.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.util.Assert;
import scatter.comment.pojo.enjoy.param.CommentEnjoyAddEnjoyParam;
import scatter.comment.pojo.enjoy.param.CommentEnjoyCancelEnjoyParam;
import scatter.comment.pojo.enjoy.po.CommentEnjoy;
import scatter.comment.pojo.subject.po.CommentSubject;
import scatter.comment.rest.componentext.CommentEnjoyOnAddOrCancelListener;
import scatter.comment.rest.enjoy.mapper.CommentEnjoyMapper;
import scatter.comment.rest.enjoy.mapstruct.CommentEnjoyMapStruct;
import scatter.comment.rest.enjoy.service.ICommentEnjoyService;
import scatter.common.pojo.form.BasePageQueryForm;
import scatter.common.rest.service.IBaseAddUpdateQueryFormServiceImpl;
import org.springframework.stereotype.Service;
import scatter.comment.pojo.enjoy.form.CommentEnjoyAddForm;
import scatter.comment.pojo.enjoy.form.CommentEnjoyUpdateForm;
import scatter.comment.pojo.enjoy.form.CommentEnjoyPageQueryForm;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

/**
 * <p>
 * 喜欢|想去|想看表 服务实现类
 * </p>
 *
 * @author yw
 * @since 2021-11-03
 */
@Slf4j
@Service
@Transactional
public class CommentEnjoyServiceImpl extends IBaseAddUpdateQueryFormServiceImpl<CommentEnjoyMapper, CommentEnjoy, CommentEnjoyAddForm, CommentEnjoyUpdateForm, CommentEnjoyPageQueryForm> implements ICommentEnjoyService {

    @Qualifier("commonDbTaskExecutor")
    @Autowired
    private ExecutorService executorService;

    @Autowired(required = false)
    private List<CommentEnjoyOnAddOrCancelListener> commentEnjoyOnAddListenerList;

    @Override
    public void preAdd(CommentEnjoyAddForm addForm,CommentEnjoy po) {
        super.preAdd(addForm,po);

    }

    @Override
    public void preUpdate(CommentEnjoyUpdateForm updateForm,CommentEnjoy po) {
        super.preUpdate(updateForm,po);

    }



    /**
     * 异步处理添加，该方法永远返回true
     * @param addEnjoytParam
     * @return
     */
    @Override
    public CommentEnjoy addEnjoy(CommentEnjoyAddEnjoyParam addEnjoytParam) {
        CommentEnjoy commentSubjectEnjoy = CommentEnjoyMapStruct.INSTANCE.addEnjoytParamToPo(addEnjoytParam);
        commentSubjectEnjoy.setTimeAt(LocalDateTime.now());
        // 楼层默认设置为1
        commentSubjectEnjoy.setFloor(Optional.ofNullable(addEnjoytParam.getFloor()).orElse(1));
        log.info("开始添加一个喜欢,subjectId={},userId={}",addEnjoytParam.getSubjectId(),addEnjoytParam.getOwnerUserId());
        boolean save = save(commentSubjectEnjoy);
        log.info("添加一个喜欢结束,subjectId={},userId={},id={}",addEnjoytParam.getSubjectId(),addEnjoytParam.getOwnerUserId(),commentSubjectEnjoy.getId());
        if (!isEmpty(commentEnjoyOnAddListenerList)) {
            for (CommentEnjoyOnAddOrCancelListener commentEnjoyOnAddListener : commentEnjoyOnAddListenerList) {
                commentEnjoyOnAddListener.onCommentEnjoyAdd(addEnjoytParam,commentSubjectEnjoy);
            }
        }
        return commentSubjectEnjoy;
    }

    /**
     * 异步处理取消，该方法永远返回 true
     * @param cancelEnjoyParam
     * @return
     */
    @Override
    public boolean cancelEnjoy(CommentEnjoyCancelEnjoyParam cancelEnjoyParam) {
        executorService.execute(()->{
            log.info("开始取消喜欢,subjectId={},userId={}",cancelEnjoyParam.getSubjectId(),cancelEnjoyParam.getOwnerUserId());
            boolean remove = remove(Wrappers.<CommentEnjoy>lambdaQuery()
                    .eq(CommentEnjoy::getSubjectId, cancelEnjoyParam.getSubjectId())
                    .eq(CommentEnjoy::getOwnerUserId, cancelEnjoyParam.getOwnerUserId())
                    .eq(!isStrEmpty(cancelEnjoyParam.getGroupFlag()), CommentEnjoy::getGroupFlag, cancelEnjoyParam.getGroupFlag())
            );
            if (!isEmpty(commentEnjoyOnAddListenerList)) {
                for (CommentEnjoyOnAddOrCancelListener commentEnjoyOnAddListener : commentEnjoyOnAddListenerList) {
                    commentEnjoyOnAddListener.onCommentEnjoyCancel(cancelEnjoyParam);
                }
            }

            log.info("取消喜欢结束,subjectId={},userId={}",cancelEnjoyParam.getSubjectId(),cancelEnjoyParam.getOwnerUserId());
        });
        return true;
    }

    @Override
    public Map<String, Page<CommentEnjoy>> listLatestEnjoyForPerSubject(List<String> subjectIds, Integer count, String groupFlag) {
        Assert.notEmpty(subjectIds,"subjectIds 不能为空");
        Assert.notNull(count,"count 不能为空");


        Map<String,Page<CommentEnjoy>> result = new HashMap<>();

        CompletableFuture[] completableFutures = subjectIds.stream().map(subjectId -> CompletableFuture.supplyAsync(() -> {
            // 我嚓，这个 page 不能提出来，否则得到的数据会是一样的
            Page page = convertPage(new BasePageQueryForm().setCurrent(1L).setSize(Integer.toUnsignedLong(count)));
            page.setSearchCount(false);
            Page page1 = page(page, Wrappers.<CommentEnjoy>lambdaQuery()
                    .eq(CommentEnjoy::getSubjectId, subjectId)
                    .eq(!isStrEmpty(groupFlag), CommentEnjoy::getGroupFlag, groupFlag)
                    .orderByDesc(CommentEnjoy::getTimeAt));
            return page1;
        }, executorService).whenComplete((r,e)->{result.put(subjectId, (Page<CommentEnjoy>)r);})).toArray(CompletableFuture[]::new);
        CompletableFuture.allOf(completableFutures).join();
        return result;
    }
}
